/*
 * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.palantir.atlasdb.table.description;

import com.palantir.atlasdb.keyvalue.api.Namespace;
import com.palantir.atlasdb.schema.AtlasSchema;
import com.palantir.atlasdb.schema.stream.StreamStoreDefinitionBuilder;
import com.palantir.atlasdb.table.description.test.StringValuePersister;
import java.io.File;
import java.util.stream.Stream;

/**
 * Schema used to test for Table API correctness and for accidental TableRenderer changes.
 * Does not get regenerated by the generateSchemas task.
 */
public class ApiTestSchema implements AtlasSchema {
    public static final AtlasSchema INSTANCE = new ApiTestSchema();

    private static final Schema GENERIC_TEST_SCHEMA = generateSchema();

    private static Schema generateSchema() {
        Schema schema = new Schema(
                "ApiTest",
                ApiTestSchema.class.getPackage().getName() + ".generated",
                Namespace.DEFAULT_NAMESPACE,
                OptionalType.JAVA8);

        schema.addTableDefinition("SchemaApiTest", new TableDefinition() {
            {
                javaTableName("SchemaApiTest");

                rowName();
                rowComponent("component1", ValueType.STRING);

                columns();
                column("column1", "c", ValueType.VAR_LONG);
                column("column2", "d", StringValuePersister.class);

                enableV2Table();
                rangeScanAllowed();
            }
        });

        schema.addTableDefinition("HashComponentsTest", new TableDefinition() {
            {
                javaTableName("HashComponentsTest");

                rowName();
                hashFirstNRowComponents(2);
                rowComponent("component1", ValueType.VAR_LONG);
                rowComponent("component2", ValueType.VAR_STRING);

                columns();
                column("column", "c", ValueType.STRING);

                rangeScanAllowed();
            }
        });

        schema.addTableDefinition("AllValueTypesTest", new TableDefinition() {
            {
                javaTableName("AllValueTypesTest");

                // This doesn't include STRING, but that is already covered by another table.
                // STRING or BLOB must be at the end of a row name, so we cannot test both.
                rowName();
                Stream.of(ValueType.values())
                        .filter(type -> type != ValueType.BLOB && type != ValueType.STRING)
                        .forEachOrdered(type -> rowComponent("component" + type, type));

                rowComponent("blobComponent", ValueType.BLOB); // has to be the last one

                columns();
                Stream.of(ValueType.values()).forEachOrdered(type -> column("column" + type, "c" + type, type));
            }
        });

        schema.addStreamStoreDefinition(
                new StreamStoreDefinitionBuilder("stream_test", "stream_test", ValueType.VAR_LONG).build());

        return schema;
    }

    public static Schema getSchema() {
        return GENERIC_TEST_SCHEMA;
    }

    // While regenerating, disable formatting.
    public static void main(String[] args) throws Exception {
        GENERIC_TEST_SCHEMA.renderTables(new File("atlasdb-client/src/integrationInput/java"));
    }

    @Override
    public Schema getLatestSchema() {
        return GENERIC_TEST_SCHEMA;
    }

    @Override
    public Namespace getNamespace() {
        return Namespace.DEFAULT_NAMESPACE;
    }
}
